<?php
/**
 * Class UserLogic
 * @package app\common\logic
 */

namespace app\common\logic;
use app\common\help\CustomerHelp;
use think\Log;



/**
 * 客户相关逻辑
 *
 * @package app\common\logic
 */
class Customer extends Base
{
    private $star_level_config_model;
    private $customer_model;

    public function __construct($data = [])
    {
        parent::__construct($data);
        $this->star_level_config_model = model('StarLevelConfig');
        $this->customer_model = model('Customer');
    }

    /**
     * 获取星级评定标准
     * @param bool $need_doc 是否需要生成规则文档
     * @return array
     */
    public function getStarLevelConfig($need_doc = false)
    {
        $return = [];
        $config_info = $this->star_level_config_model->getList([], 100, false, true, true);
        $config_info = $config_info['data'];
        $return['config_info'] = $config_info;
        //生成规则文案
        if (!$need_doc) {
            return $return;
        }

        $doc = "<table class='layui-table'><thead><tr><th>等级</th><th>评定标准</th></tr></thead>";

        foreach ($config_info as $v) {
            $star = str_repeat("<i class='layui-icon layui-icon-star-fill'></i>", $v['star_level']);
            if ($v['desc']) {
                $config = $v['desc'];
            } else {
                if ($v['revenue_max'] == 0) {
                    $config = "{$v['revenue_min']} < 业务额";
                } else {
                    $config = "{$v['revenue_min']} < 业务额 <= {$v['revenue_max']}";
                }
            }
            $doc .= "<tr><td>{$star}</td><td>{$config}</td></tr>";
        }

        $doc .= "</table>";

        $return['doc'] = $doc;

        return $return;
    }

    /**
     * 提交一个客户信息
     * @param array $data
     * @param array $user_info
     * @param int $id
     * @return mixed
     */
    public function submitCustomer(array $data, array $user_info, $id = 0)
    {
        if (empty($data)) {
            exception('缺少客户信息！');
        }

        $data = array_map(function ($v) {
            return addslashes(htmlspecialchars(trim($v)));
        }, $data);

        if (empty($user_info)) {
            exception('无法获取登陆人员信息，建议尝试重新登录！');
        }

        //必填字段验证
        if (empty($data['company_name'])) {
            exception('请填写客户单位名称！');
        }

        $data['province_id'] = empty($data['province_id']) ? 0 : (int)$data['province_id'];
        $data['city_id'] = empty($data['city_id']) ? 0 : (int)$data['city_id'];
        $data['district_id'] = empty($data['district_id']) ? 0 : (int)$data['district_id'];

        //是否是一般纳税人
        $data['is_general_taxpayer'] = isset($data['is_general_taxpayer']) && in_array($data['is_general_taxpayer'], [0,1]) ? (int)$data['is_general_taxpayer'] : 0;

        if ($id > 0) {
            $old_info = $this->customer_model->getInfo(['id' => $id]);
            if (empty($old_info)) {
                exception('该客户信息不存在或已被删除，请刷新页面后重试！');
            }

            //税号是否发生改变
            if (!empty($data['taxpayer_identity_numbe']) && $old_info->taxpayer_identity_numbe != $data['taxpayer_identity_numbe']) {
                //检查新税号是否可用
                $same_tax_number_info = $this->customer_model->getInfo([
                    'taxpayer_identity_numbe' => $data['taxpayer_identity_numbe'],
                ], 'taxpayer_identity_numbe');
                if ($same_tax_number_info) {
                    exception('该税号已经存在，请检查！');
                }
            }

            if ($old_info->company_name != $data['company_name'] && $this->customer_model->getInfo([
                'company_name' => $data['company_name']
            ], 'company_name')) {
                exception('该公司名字已经存在，检查！');
            }

            //客户编号数据检查
            /*$customer_number_prefix = $data['customer_number_prefix'];
            if (!preg_match('/[A-Z]{3}/', $customer_number_prefix)) {
                exception('客户编号前缀格式错误(只能由3个字母组成)！');
            }
            $customer_number_number = $data['number'];//组成编号的序号
            $customer_number_number = (int)$customer_number_number;
            if (!preg_match('/\d{1,5}/', $customer_number_number)) {
                exception('客户编号序号格式错误(只能由最多5位数字组成)！');
            }
            $customer_number = $customer_number_prefix . sprintf("%05d", $customer_number_number);

            if ($old_info->customer_number != $customer_number) {
                //检查编号是否已经被占用
                $same_customer_number_info = $this->customer_model->getInfo([
                    'customer_number' => $customer_number,
                ], 'customer_number');
                if ($same_customer_number_info) {
                    exception('该客户编号已经存在，请检查！');
                }
            }

            $data['number'] = $customer_number_number;
            $data['customer_number'] = $customer_number;*/

            /*去掉对客户编号的编辑*/
            unset($data['customer_number_prefix']);
            unset($data['number']);
            unset($data['customer_number']);

            $res = $this->customer_model->saveDate($id, $data);
            return $res === false ? false : true;
        } else {
            //生成客户编号
            $customer_number_info = $this->getCustomerNumber();

            $data['customer_number'] = $customer_number_info['customer_number'];
            $data['number'] = $customer_number_info['number'];

            //检查客户是否已经存在：由于纳税人识别号改为了非必填，因此不再使用纳税人号进行验证，暂时只在填写了纳税人识别号时才验证
            if (!empty($data['taxpayer_identity_numbe'])) {
                $info = $this->customer_model->getInfo([
                    'taxpayer_identity_numbe' => $data['taxpayer_identity_numbe'],
                ], 'taxpayer_identity_numbe');
                if ($info) {
                    exception('该税号已经存在，请勿重复添加！');
                }
            }

            if ($this->customer_model->getInfo([
                'company_name' => $data['company_name']
            ], 'company_name')) {
                exception('该公司名字已经存在，请勿重复添加！');
            }

            //录入相关信息
            $data['add_uid'] = $user_info['id'];
            $data['is_delete'] = 0;
            $data['create_time'] = time();
            //$data['sign_company_code'] = isset($user_info['code'][0]) ? $user_info['code'][0] : '';

            return $this->customer_model->addData($data);
        }
    }

    /**
     * 生成客户编号规则：LBH+序号
     * @return string
     */
    public function getCustomerNumber()
    {
        $last_number = $this->customer_model->getLastCustomerNumber();

        $prefix = logic('Config')->getOtherSetByName(CUSTOMER_NUMBER_PREFIX_KEY);
        $prefix = $prefix ? $prefix :'LBH';
        $number = $last_number + 1;
        $customer_number = $prefix . sprintf("%05d", $number);
        return [
            'number' => $number,
            'customer_number' => $customer_number,
        ];
    }

    /**
     * 获取客户列表
     * @param array $where
     * @param array $user_info
     * @param int $limit
     * @return array
     */
    public function getList(array $where, array $user_info, $limit = 20)
    {
        $list = $this->customer_model->getList($where, $limit);
        $list_copy = $list->toArray();

        $region_arr = [];
        if ($list_copy['data']) {
            $region_id = array_merge(array_column($list_copy['data'], 'province_id'), array_column($list_copy['data'], 'city_id'), array_column($list_copy['data'], 'district_id'));
            $region_id = array_filter(array_unique($region_id));
            $region_id = array_map(function ($v){
                return (int)$v;
            }, $region_id);

            if (!empty($region_id)) {
                $region_model = model('Region');
                $region_list = $region_model->getList(['region_id' => $region_id], count($region_id), false, 'region_id,region_name');
                foreach ($region_list['data'] as $v) {
                    $region_arr[$v['region_id']] = $v['region_name'];
                }
                unset($region_model,$region_list,$region_id);
            }
        }

        foreach ($list as $v) {

            $address_prefix = '';
            $province = '';
            $city = '';
            $district = '';
            if (isset($v->province_id) && $v->province_id > 0) {
                $province = isset($region_arr[$v->province_id]) ? $region_arr[$v->province_id] . ' ' : '';
                $address_prefix .= $province;
            }

            if (isset($v->city_id) && $v->city_id > 0) {
                $city = isset($region_arr[$v->city_id]) ? $region_arr[$v->city_id] . ' ' : '';
                $address_prefix .= $city;
            }

            if (isset($v->district_id) && $v->district_id > 0) {
                $district = isset($region_arr[$v->district_id]) ? $region_arr[$v->district_id] . ' ' : '';
                $address_prefix .= $district;
            }

            $v->address_prefix = $address_prefix;
            $v->province = $province;
            $v->city = $city;
            $v->district = $district;
        }
        return $list;
    }

    public function getInfo(array $where)
    {
        $info = $this->customer_model->getInfo($where);
        if (!empty($info)) {
            //处理地址信息
            $region_model = model('Region');
            $address_prefix = '';
            if ($info->province_id > 0) {
                $region_info = $region_model->getInfo(['region_id' => $info->province_id], 'region_name');
                $address_prefix .= !empty($region_info['region_name']) ? $region_info['region_name'].' ' : '';
            }
            if ($info->city_id > 0) {
                $region_info = $region_model->getInfo(['region_id' => $info->city_id], 'region_name');
                $address_prefix .= !empty($region_info['region_name']) ? $region_info['region_name'].' ' : '';
            }
            if ($info->district_id > 0) {
                $region_info = $region_model->getInfo(['region_id' => $info->district_id], 'region_name');
                $address_prefix .= !empty($region_info['region_name']) ? $region_info['region_name'].' ' : '';
            }
            $info->address_prefix = $address_prefix;

            //处理信息录入人
            if ($info->add_uid > 0) {
                $admin_user_model = model('AdminUser');
                $user_info = $admin_user_model->getInfo(['id' => $info->add_uid], 'username');
                $info->add_user_name = isset($user_info->username) ? $user_info->username : '';
            } else {
                $info->add_user_name = '';
            }
        }

        return $info;
    }

    /**
     * (放入回收站)删除一条/多条 客户信息
     * @param array $ids
     * @return bool
     */
    public function deleteData(array $ids)
    {
        if (empty($ids)) {
            return true;
        }

        $data = [
            'is_delete' => 1,
        ];
        foreach ($ids as $id) {
            $res = $this->customer_model->saveDate($id, $data);
            if ($res === false) {
                return false;
            }
        }

        return true;
    }

    /**
     * 批量导入客户数据
     *
     * @param array $user_info
     * @return mixed
     */
    public function batchImportData(array $user_info)
    {
        if (empty($user_info)) {
            exception('无法获取登录信息，请重新登录后尝试！');
        }

        $upload_logic = logic('Upload');
        /*设置上传根路径*/
        $upload_logic->setUploadPath(UPLOAD_FILE_PATH . '/import_customer/');
        $res = $upload_logic->uploadFile();//成功后，为上传的文件路径，此处一次只能上传一张

        if ($res && is_array($res)) {
            Log::record('文件上传成功：' . $res[0]);
            $import_res = $this->handleOrderExcelDataToTable($res[0], $user_info);
            return $import_res;
        } else {
            exception($upload_logic->getErrorInfo() ? $upload_logic->getErrorInfo() : '导入失败！');
        }
    }

    /**
     * 把Excel 表里面的订单数据导入到数据库中
     *
     * @author mayy
     * @date 2017-9-30
     * @param $file_name
     * @param $user_info
     * @return mixed
     */
    private function handleOrderExcelDataToTable($file_name, $user_info)
    {
        $header_fields_realtion = CustomerHelp::customerDataExcelHeader();
        $excel_data = $this->getDataFromExcel($file_name, $header_fields_realtion, true, false);
        $excel_header_data = $excel_data['header'];
        $excel_data = $excel_data['data'];
        if (empty($excel_data)) {
            exception('文件内容为空！');
        }

        $upload_success_time = date('Y-m-d H:i:s');

        //过滤掉空白行，行内所有字段数据都为空，则认为是空白行
        foreach ($excel_data as &$v) {
            $is_empty_row = true;
            foreach ($v as $v_field) {
                if (!empty($v_field)) {
                    $is_empty_row = false;
                    break;
                }
            }
            if ($is_empty_row) {
                unset($v);
            }
        }

        if (empty($excel_data)) {
            exception('文件内容为空！');
        }

        //excel字段检查
        $check_excel_fields = $this->checkOrderDataExcelFilds($excel_header_data);
        if (!$check_excel_fields) {
            exception('请按照模板文件格式上传excel文件，确保表头未被修改！');
        }

        $failed_customer_list = [];

        //分别取出省 、 市 、 区县 的信息用于查询
        $province_arr = array_unique(array_filter(array_column($excel_data, 'province')));
        $city_arr = array_unique(array_filter(array_column($excel_data, 'city')));
        $district_arr = array_unique(array_filter(array_column($excel_data, 'district')));

        $region_model = model('Region');
        $province_id_relation_arr = $this->getRegionIdByName($province_arr, 1, $region_model);
        $city_id_relation_arr = $this->getRegionIdByName($city_arr, 2, $region_model);
        $district_id_relation_arr = $this->getRegionIdByName($district_arr, 3, $region_model);

        $success_counts = 0;
        foreach ($excel_data as $k => $v) {
            //数据处理
            if (empty($v['company_name'])) {
                $failed_customer_list[] = [
                    'row' => $k,
                    'reason' => '公司名字为空',
                ];
                continue;
            }

            /*检查公司名字是否已经存在*/
            if ($this->customer_model->getInfo([
                    'company_name' => $v['company_name']
                ], 'company_name')) {
                $failed_customer_list[] = [
                    'row' => $k,
                    'reason' => '公司名字（'.$v['company_name'].'）已经存在',
                ];
                continue;
            }

            /*不再强制验证纳税人识别号*/
            /*if (empty($v['taxpayer_identity_numbe'])) {
                $failed_customer_list[] = [
                    'row' => $k,
                    'reason' => '纳税人识别号为空',
                ];
                continue;
            }*/

            //检查税号是否存在
            if (!empty($v['taxpayer_identity_numbe']) && $this->customer_model->getInfo([
                'taxpayer_identity_numbe' => $v['taxpayer_identity_numbe']
            ], 'taxpayer_identity_numbe')) {
                $failed_customer_list[] = [
                    'row' => $k,
                    'reason' => '纳税人识别号（'.$v['taxpayer_identity_numbe'].'）已经存在',
                ];
                continue;
            }

            //数据处理成可以入库的结构
            $customer_number_info = $this->getCustomerNumber();
            $customer_data = [
                'customer_number' => $customer_number_info['customer_number'],
                'company_name' => $v['company_name'],
                'short_name' => $v['short_name'],
                'taxpayer_identity_numbe' => $v['taxpayer_identity_numbe'],
                'province_id' => isset($province_id_relation_arr[$v['province']]) ? $province_id_relation_arr[$v['province']] : '',
                'city_id' => isset($city_id_relation_arr[$v['city']]) ? $city_id_relation_arr[$v['city']] : '',
                'district_id' => isset($district_id_relation_arr[$v['district']]) ? $district_id_relation_arr[$v['district']] : '',
                'address' => $v['address'],
                'legal_person' => $v['legal_person'],
                'revenue' => $v['revenue'],
                'star_level' => $this->coupute_star_level($v['revenue'], $v['star_level']),
                'business_scope' => $v['business_scope'],
                'tax_bureau' => $v['tax_bureau'],
                'is_general_taxpayer' => ($v['is_general_taxpayer'] == '否' || $v['is_general_taxpayer'] === '0') ? 0 : 1,//默认：是
                'financial_software' => $v['financial_software'],
                'tax_bureau_manager' => $v['tax_bureau_manager'],
                'tax_bureau_manager_tel' => $v['tax_bureau_manager_tel'],
                'tax_bureau_manager_qq' => $v['tax_bureau_manager_qq'],
                'tax_bureau_manager_wx' => $v['tax_bureau_manager_wx'],
                'tax_bureau_manager_email' => $v['tax_bureau_manager_email'],
                'financial_deputy_majordomo' => $v['financial_deputy_majordomo'],
                'financial_deputy_majordomo_tel' => $v['financial_deputy_majordomo_tel'],
                'financial_deputy_majordomo_qq' => $v['financial_deputy_majordomo_qq'],
                'financial_deputy_majordomo_wx' => $v['financial_deputy_majordomo_wx'],
                'financial_deputy_majordomo_email' => $v['financial_deputy_majordomo_email'],
                'financial_deputy_manager' => $v['financial_deputy_manager'],
                'financial_deputy_manager_tel' => $v['financial_deputy_manager_tel'],
                'financial_deputy_manager_qq' => $v['financial_deputy_manager_qq'],
                'financial_deputy_manager_wx' => $v['financial_deputy_manager_wx'],
                'financial_deputy_manager_email' => $v['financial_deputy_manager_email'],
                'accountant_leader' => $v['accountant_leader'],
                'accountant_leader_tel' => $v['accountant_leader_tel'],
                'accountant_leader_qq' => $v['accountant_leader_qq'],
                'accountant_leader_wx' => $v['accountant_leader_wx'],
                'accountant_leader_email' => $v['accountant_leader_email'],
                'tax_discount' => $v['tax_discount'],
                'note' => $v['note'],
                'number' => $customer_number_info['number'],
                'add_uid' => $user_info['id'],
                'create_time' => time(),
                //'sign_company_code' => $sign_company_code,
            ];

            $res = $this->customer_model->addData($customer_data);
            if (!$res) {
                $failed_customer_list[] = [
                    'row' => $k,
                    'reason' => '插入数据库失败（可重试）',
                ];
                continue;
            } else {
                $success_counts++;
            }
        }

        return [
            'total_counts' => count($excel_data),
            'success_counts' => $success_counts,
            'failed_customer_list' => $failed_customer_list,
            'upload_complete_time' => $upload_success_time,
        ];
    }

    /**
     * 从文件中取出数据
     * @param $file_name
     * @param array $field_name_map
     * @param bool $need_header
     * @param bool $only_header
     * @return array
     */
    private function getDataFromExcel($file_name, array $field_name_map = [], $need_header = true, $only_header = false)
    {
        if (!file_exists($file_name)) {
            exception('文件不存在！');
        }
        vendor("PHPExcel.PHPExcel");

        //get ext of file
        $tmp_arr = explode('.', $file_name);
        $exts = $tmp_arr[count($tmp_arr) - 1];

        $objReader = null;
        if ($exts == 'xls') {
            $objReader = new \PHPExcel_Reader_Excel5();
        } else if ($exts == 'xlsx') {
            $objReader = new \PHPExcel_Reader_Excel2007();
        } else {
            exception("Error excel file");
        }

        //read data
        $PHPExcel       = $objReader->load($file_name);
        $currentSheet   = $PHPExcel->getSheet(0);
        $allColumn      = $currentSheet->getHighestColumn();
        $allRow         = $currentSheet->getHighestRow();

        //解决 列超出 Z
        ++$allColumn;

        $header = [];
        if ($need_header) {
            /*使用 != 进行判断， 解决 列超出 Z 的问题 */
            for ($currentColumn_header = 'A'; $currentColumn_header != $allColumn; $currentColumn_header++) {
                //location of one data
                $address_header = $currentColumn_header . 1;
                //save to array
                $header[] = trim((string)$currentSheet->getCell($address_header)->getValue());
            }
        }

        $data = [];
        for ($currentRow =2; $currentRow <= $allRow; $currentRow++) {
            for ($currentColumn = 'A'; $currentColumn != $allColumn; $currentColumn++) {
                //location of one data
                $address = $currentColumn . $currentRow;
                //save to array
                $data[$currentRow-1][$field_name_map[$currentColumn]] = trim((string)$currentSheet->getCell($address)->getValue());
            }
        }

        if ($only_header) {
            return $header;
        }

        return [
            'header' => $header,
            'data' => $data
        ];
    }

    /**
     * 检查订单数据excel 的表头是否合法
     * @param array $execl_header
     * @return bool
     */
    private function checkOrderDataExcelFilds(array $execl_header)
    {
        $customer_data_template = ROOT_PATH . '/public/excel_template/customer-list-template.xlsx';

        if (!file_exists($customer_data_template)) {
            exception('模板文件不存在，请联系工程师处理！');
        }

        $template_header = $this->getDataFromExcel($customer_data_template, [], true, true);
        if (empty($template_header)) {
            exception('模板文件内容为空！');
        }
        $template_header = array_filter($template_header);
        $execl_header = array_filter($execl_header);

        if (http_build_query($template_header) != http_build_query($execl_header)) {
            return false;
        }

        return true;
    }

    /**
     * @param array $region_name_arr
     * @param int $type 1省，2：市，3：区县
     * @param null $region_model
     * @return array
     */
    public function getRegionIdByName(array $region_name_arr, $type = 1, $region_model = null)
    {
        if ($region_model == null) {
            $region_model = model('Region');
        }

        if (empty($region_name_arr)) {
            return [];
        }

        $province_id_relation_arr = [];

        foreach ($region_name_arr as $v) {
            if (empty($v)) {
                continue;
            }
            $region_info = $region_model->getInfo([
                'region_name' => $v,
                'region_type' => $type,
            ], 'region_id');
            $province_id_relation_arr[$v] = empty($region_info->region_id) ? 0 : $region_info->region_id;
        }

        return $province_id_relation_arr;
    }

    /**
     *  计算星级
     * @param $revenue
     * @param $revenue
     * @param int $star_level
     * @return int
     */
    public function coupute_star_level($revenue, $star_level = 0)
    {
        //如果已经指定了星级，则直接使用
        if ($star_level > 0) {
            return $star_level;
        }

        static $star_level_config;
        if ($star_level_config == null) {
            //获取星级配置
            $star_level_config_info = $this->getStarLevelConfig();
            $star_level_config = $star_level_config_info['config_info'];
        }

        $star_counts = 0;
        //如果没有指定，才计算
        for ($i = 0; $i < count($star_level_config); $i++) {
            if ($star_level_config[$i]['desc'] != '') {
                //默认值,不用处理
                if ($revenue == 0) {
                    $star_counts = $star_level_config[$i]['star_level'];
                    break;
                }
                continue;
            }

            //需要通过业务额具体的区间进行判断：如果输入的数字小于当前最小值，则使用默认0星即可，因为规则数字是从小到大
            if ($star_level_config[$i]['revenue_min'] > $revenue) {
                break;
            }

            if ($star_level_config[$i]['revenue_max'] == 0 || $revenue <= $star_level_config[$i]['revenue_max']) {
                $star_counts = $star_level_config[$i]['star_level'];
                break;
            }
        }
        return $star_counts;
    }

    /**
     * 搜索客户列表
     * @param array $where
     * @param mixed $fields
     * @param array $user_info
     * @param int $limit
     */
    public function searchList(array $where, $fields = true, array $user_info, $limit = 20)
    {
        $list = $this->customer_model->getList($where, $limit, false, $fields, true);
        return $list;
    }
}